#ifndef SCRIPTMGR_H
#define SCRIPTMGR_H

#include "Common.h"
#include "Resource.h"
#include "Hsm.h"
#include "String.h"


#define		BUILD_REVISION  1001


#define MAKE_SCRIPT_VERSION(major, minor) (uint32)(((uint16)major << 16) | ((uint16)minor))


class ScriptMgr;
class WorldPacket;
class BSSocketPtr;



namespace AIScript{
	class AIInterface;
	class AIScript;

	#define TO_SCRIPT_AI(ptr) dynamic_cast<AIScript *>(ptr) 
	#define TO_AI_INTERFACE(ptr) dynamic_cast<AIInterface *>(ptr) 

}


#define SCRIPT_MODULE void*
#define ADD_AI_FACTORY_FUNCTION(cl) static AIScript * Create(Resource * c) { return new cl(c); }
#define ADD_INTERFACE_FACTORY_FUNCTION(aii)  static AIInterface * Create(Resource * res) {	return new aii(res);	}

enum ScriptTypes
{
	SCRIPT_TYPE_MISC					= 0x01,
	SCRIPT_TYPE_ENGINE_EXT					= 0x02,
	SCRIPT_TYPE_SCRIPT_ENGINE				= 0x20,
	SCRIPT_TYPE_SCRIPT_ENGINE_JS				= 0x21,   //javascript
};


typedef bool(*tProcessMessage)(ResourcePtr & socket,WorldPacket & packet);

enum GatewayCommandResultFlag
{
	CGRF_NONE		= 0x00,	//网关命令无效
	CGRF_ERROR		= 0x01,	//命令执行失败
	CGRF_SUCCEED		= 0x02,	//网关命令执行成功
	CGRF_FORWARD		= 0x04,	//网关命令转递
	CGRF_RETURN		= 0x08,	//向命令源发送信息，返回记录命令值
	SCR_ERROR		= CGRF_ERROR,	//网关命令执行失败
	SCR_SUCCEED		= CGRF_SUCCEED,	//网关命令执行成功
	SCR_RETURN_ERROR	= CGRF_ERROR|CGRF_RETURN,	//网关命令执行错误，回写命令参数
	SCR_RETURN_SUCCEED	= CGRF_SUCCEED|CGRF_RETURN,	//网关命令执行成功，回写命令参数
	SCR_FORWARD		= CGRF_FORWARD,		//网关命令未执行只转递命令
	SCR_FORWARD_ERROR	= CGRF_ERROR|CGRF_FORWARD,	//网关命令执行失败，转递命令
	SCR_FORWARD_SUCCEED	= CGRF_SUCCEED|CGRF_FORWARD,	//网关命令执行成功，转递命令
	SCR_FORWARD_RETURN_ERROR	= CGRF_ERROR|CGRF_FORWARD|CGRF_RETURN,	//网关命令执行失败，转发和回写命令参数
	SCR_FORWARD_RETURN_SUCCEED	= CGRF_SUCCEED|CGRF_FORWARD|CGRF_RETURN	//网关命令执行成功，转发和诙谐命令参数
	
};

typedef int(*tGatewayCommand)( void * gwinfo);

/* 参数 datainfo 为JSON 数据 标准头格式
	Json::Value root;
	root["server_cmd"]   	命令类型
	root["server_src"]	发送命令源服务器
	root["server_type"]	发送命令源服务器类型
	root["server_dest"]	目标服务器，如果为0表示广播整个服务器
	root["server_parent"]	发送命令源服务器的父级服务器
	root["data"] 		用户的自定义数据(JSON)

*/
typedef int(*tServerCommand)(void * datainfo);

enum ServerHookTypes
{
	SERVER_HOOK_START 			=   0x01,	//服务器启动
	SERVER_HOOK_END					,	//服务器停机
	SERVER_HOOK_JOIN				,	//服务器加入服务器组
	SERVER_HOOK_PART				,	//服务器离开服务器组
	SERVER_HOOK_LOOP				,	//服务器循环事件
	SERVER_HOOK_SLAVE_CLOSE				,	//子服务器进入关闭状态
	SERVER_HOOK_SERVER_CHOICE			,	//定制服务器个性选择，返回Server_id 如果返回0，进入标准选择流程
};

typedef int(*tServerHook)(uint32 serverid);


/* Factory Imports (from script lib) */
typedef AIScript::AIScript*(*exp_create_ai)(Resource * pUnit);

typedef AIScript::AIInterface *(*exp_create_interface)(Resource * pUnit);

typedef void(*exp_script_register)(ScriptMgr * mgr);
typedef uint32(*exp_get_script_type)();

typedef uint32(*exp_get_version)();

/* Hashmap typedefs */
typedef HM_NAMESPACE::hash_map<uint32, exp_create_ai> AICreateMap;
typedef HM_NAMESPACE::hash_map<uint32, exp_create_interface> InterfaceCreateMap;
typedef HM_NAMESPACE::hash_map<uint16,tProcessMessage>  ServerProcessMap;
typedef HM_NAMESPACE::hash_map<uint16,tGatewayCommand>  GatewayCommandMap;
typedef HM_NAMESPACE::hash_map<uint16,tServerCommand>  ServerCommandMap;
typedef HM_NAMESPACE::hash_map<uint16,tServerHook>  ServerHookMap;

//typedef set<QuestScript*> QuestScripts;
typedef std::list<SCRIPT_MODULE> LibraryHandleMap;


//HTTPD 处理注册函数
typedef int(*tHttpdRequestHandle)( void * conn, void * req, void* resp);

#define MAX_SCRIPTS 1000

class SERVER_DECL ScriptMgr : public Singleton<ScriptMgr>
{
public:

	ScriptMgr();
	~ScriptMgr();

	friend class HookInterface;

	void LoadScripts(bool isWorldServer = false);
	void UnloadScripts();

	AIScript::AIScript * CreateAIScriptClass(uint16 ai_index,Resource * pUnit);
	bool	isPresentAIScriptClass(uint16 ai_type,uint16 ai_index);

	AIScript::AIInterface * CreateAIInterfaceClass(uint16 ai_index,Resource * pUnit);
	bool	isPresentAIInterfaceClass(uint16 ai_type,uint16 ai_index);

	tProcessMessage	getProcessHandle(const uint16 & entry);
	bool	isPresentProcessHandle(const uint16 & entry);

	tGatewayCommand	getGWCommandHandle(const uint16 & entry);
	bool	isPresentGWCommandHandle(const uint16 & entry);
	
	tServerCommand getServerCommandHandle(const uint16 & entry);
	bool	isPresentServerCommandHandle(const uint16 & entry);
	
	tServerHook	getServerHook(const uint16 & entry);
	bool	isPresentServerHook(const uint16 & entry);

	bool CallScriptedItem(Resource *  pItem, Resource * pPlayer);
	
	void register_ai_script(uint16 ai_type, uint16 ai_entry, exp_create_ai callback);
	void register_interface_script(uint16 ai_type, uint16 ai_entry, exp_create_interface callback);
	//void register_dummy_spell(uint32 entry, exp_handle_dummy_spell callback);
	//void register_quest_script(uint32 entry, QuestScript * qs);
	bool isPresentAIScript(uint16 ai_type,uint16  ai_entry);
	bool isPresentAIInterface(uint16 ai_type,uint16 ai_entry);

	void register_server_process(const uint16 & entry,tProcessMessage callback);
	
	void register_gateway_command(const uint16 entry,tGatewayCommand callback);
	void register_server_command(const uint16 entry,tServerCommand callback);
	void register_server_hook(const uint16 entry,tServerHook callback);

	//注册HTTPD的处理函数
	static void register_httpd_request_handle(tHttpdRequestHandle handle)
	{
		ScriptMgr::_httpRequestHandle = handle;
	}
	
	static tHttpdRequestHandle  get_httpd_requert_handle(){	return ScriptMgr::_httpRequestHandle ; }
protected:
	AICreateMap 		_creatures;
	InterfaceCreateMap	_interfaces;
	//HandleDummySpellMap	 _spells;
	LibraryHandleMap 	_handles;

	ServerProcessMap	_process;
	GatewayCommandMap	_commands;
	ServerCommandMap	_server_commands;
	ServerHookMap		_hooks;
	//QuestScripts 		_questscripts;
	//
	static tHttpdRequestHandle	   _httpRequestHandle;
};


namespace  AIScript {
	enum AIType
	{
        	AITYPE_NONE = 0,
		AITYPE_USER
	};

	class SERVER_DECL AIScript
	{
	public:
		WGS_AUTO_MUTEX;
		AIScript(Resource * pUnit);
		virtual ~AIScript() {};

		virtual void OnLoad() {}
		virtual void OnUnload()	{}

		virtual void AIUpdate() {}
		
		virtual void OnActivate(ResourcePtr & pParter) {}
		virtual void OnDeactivate(ResourcePtr & pParter) {}

		//返回Ture 系统将不做默认的Update 处理
		virtual bool OnUpdate(const uint32 & p_time)	{	return false;	}


		virtual void StringFunctionCall(const char * pFunc) {}

		void RegisterAIUpdateEvent(uint32 frequency);
		void ModifyAIUpdateEvent(uint32 newfrequency);
		void RemoveAIUpdateEvent();

		/*相应系统Message事件，如果脚本Handle返回True 否则返回 False */
		virtual bool OnMessage(NameValuePairList * params) { 	return false;	}

		/*响应Event 如果需要中断事件Chain 返回 false*/
		virtual uint8 OnEvent(ResourceEvent * event)	{	return EVERET_NONE;	}

		virtual void OnCreate() {}
		virtual void Destroy() { m_Unit = 0 ;delete this; }

		virtual void setAIType(const uint8 & type)	{	m_type = type; }
		virtual const uint8 & getAIType(void)	{	return m_type;	}

		Resource  * GetUnit() { return m_Unit; }

	protected:
		Resource 	*m_Unit;
		uint8	         m_type;
	};



	class SERVER_DECL AIInterface :public Hsm
	{
	public:
		WGS_AUTO_MUTEX;
		virtual void Load(void);
		virtual void Unload(void);
	
		//检查接口最后的更新时间是否超过checktime 超过返回Ture 未超过返回false
		virtual bool checkUpdate(const uint32 & p_time,const uint32 & checktime);
		
		//检查接口是否可在指定的时间间隔可更新，如果可以更新则调用Update 事件
		virtual bool checkAndUpdate(const uint32 & p_time,const uint32 & checktime);
			
		virtual void Update(const uint32 & p_time);

		virtual Resource * GetUnit() { return m_Unit; }

		virtual uint8 getAIType() { return m_AIType; }
		virtual void setAIType(uint8 aitype)  {	  m_AIType = aitype; }


		//激活AIUpdate事件,是否循环出?,updatetime为 0 则 关闭AI更新?
		virtual void AIUpdate(const uint32 & updatetime, bool hasLoop = false);

		virtual bool getEnabled(void)	{	return m_scriptEnabled;	}
		virtual void setEnabled(bool enabled)	{	m_scriptEnabled = enabled;	}
		
		virtual void  Activate( ResourcePtr & pParter );
		virtual void  Deactivate( ResourcePtr & pParter );
		/*调用脚本系统Message处理脚本 */
		virtual bool  SendMessage(NameValuePairList * params = 0);

		/*发送 分发事件消息*/
		virtual	uint8	SendEvent(ResourceEvent * event);
		/*分发事件 停止分发返回false*/
		virtual uint8	HandleEvent(ResourceEvent * event);

		/*是否载入子对象*/
		virtual bool	isLoadChildren(void);

		virtual void Destroy();

		const uint32 &  getCurrentUpdateTime(void)	{	return m_currentUpdateTimer;	}
		const uint32 &  getLastUpdateTime(void)	{	return m_lastUpdateTimer;	}
		//得到两次更新的时间帧
		const uint32 &  getFPS(void)		{	return m_fps;	}
	protected:

		static HSMState hsm_idle(AIInterface *me, HSMEvent const *e);
		Resource *	m_Unit;

		uint8 m_AIType;

		uint32	m_AIUpdateTimer;
		uint32	m_AIUpdateTimerDiff;
		bool	m_AIUpdateLoop;


		//最后Update 时间
		uint32	m_lastUpdateTimer;
		uint32	m_currentUpdateTimer;
		//距离最后一次更新的时间间隔 p_time - m_lastUpdateTimer
		uint32	m_fps;

		bool	m_scriptEnabled;
	public:
		AIInterface(Resource * pUnit);
		virtual ~AIInterface();
		
	};


	#define VCALL(x) {HSMStateHandler result = me->x(); if (result != 0) { return HSM_TRAN(result);}}

}


#define sScriptMgr ScriptMgr::getSingleton()

#endif
